import plugin from '../../lib/plugins/plugin.js'
import { segment } from "oicq";
import cfg from '../../lib/config/config.js'
import fs from 'fs'
import co from '../../lib/common/common.js'
import gsCfg from '../genshin/model/gsCfg.js'
import axios from 'axios'
import MD5 from 'md5'
const normal_path = process.cwd() + '/plugins/miao-plugin/resources/profile/normal-character/'
const super_path = process.cwd() + '/plugins/miao-plugin/resources/profile/super-character/'
let path
let cd = false
let FiguretypeUser = {}
//以下是用户配置项
//=========================================================================================
const original = true //是否屏蔽群友获取面板图原图，true为屏蔽，false为不屏蔽，主人不受限制
const panelList = true //是否只能主人查看面板图列表，true为只能主人，false为全员
const isRemove =  false //是否开启抠图功能，true为开启，false为关闭，开启了默认覆盖ap-plugin的抠图功能
const URL = '' //填写抠图API，配置教程：https://www.wolai.com/sSZM1AHnBULxyc4s4hKquF
//=========================================================================================

/* 
作者: 花海里的秋刀鱼(717157592)
首发群:258623209
版本: 1.65 
更新内容: 新增MD5图片检测，新增一键通过，支持合并转发信息一键上传，支持上传彩蛋面板图，支持直接上传多张面板图，支持删除角色全部面板图,增加屏蔽群员原图选项，面板图列表选项，抠图功能，修正图像命名问题导致上传图片覆盖原图片
示范指令: 上传甘雨(彩蛋)面板图，#甘雨(彩蛋)面板图列表，#删除甘雨(彩蛋)面板图1，#删除甘雨全部面板图，通过(彩蛋)(得私聊引用信息) 
时间: 2023.3.3
*/
export class example extends plugin {
  constructor() {
    super({
      name: '上传面板图',
      dsc: '默认覆盖喵喵2.1.5版本后自带的此功能',
      event: 'message',
      priority: -114514,
      rule: [{
          reg: '^#?上传(.*)面板图$',
          fnc: 'uploadPanel'
        },
        {
          reg: '^#?(.*)面板图列表$',
          fnc: 'letMeLook'
        },
        {
          reg: '^#?删除(.*)(全部)?面板图',
          fnc: 'deletePanel',
          permission: 'master'
        },
        {
          reg: '^#?通过(彩蛋)?$',
          fnc: 'adopt'
        },
        {
          reg: '^#?(获取|给我|我要|求|发|发下|发个|发一下)?原图(吧|呗)?$',
          fnc: 'shield'
        },
        {
          reg: '^#?(去背景|抠图|扣图)$',
          fnc: 'removeBackGround'
        },
        {
          reg: '^#?查询面板图请求$',
          fnc: 'selectAdopt'
        },
        {
          reg: '^#?一键(通过|拒绝)(全部)?面板图',
          fnc: 'adoptAll'
        }
      ]
    })
  }


  async uploadPanel(e) {
    if(cd) return e.reply('我知道你很急，但你先别急')
    if (e.msg.includes('彩蛋')) {
      path = super_path
    }else{
      path = normal_path
    }
    let id = await this.getId(e)
    if (!id) return e.reply('请输入角色名')
    let source
    let imageMessages = []
    if (e.isGroup) {
      source = (await e.group.getChatHistory(e.source ?.seq, 1)).pop()
    } else {
      source = (await e.friend.getChatHistory((e.source ?.time + 1), 1)).pop()
    }
    if (source) {
      for (let val of source.message) {
        if (val.type === 'image') {
          imageMessages.push(val.url)
        }else if (val.type === 'xml') { // 支持合并转发消息内置的图片批量上传，喵喵 喵喵喵？ 喵喵喵喵
          if(!e.isMaster) return e.reply('只有主人能上传合并转发信息面板图')
          let resid = val.data.match(/m_resid="(.*?)"/)[1]
          if (!resid) break
          let message = await Bot.getForwardMsg(resid)
          for (const item of message) {
            for (const i of item.message) {
              if (i.type === 'image') {
                imageMessages.push(i.url)
              }
            }
      }      
    }
  }
}else{
    imageMessages = e.img
  }  
    if (!imageMessages.length) return e.reply('消息中未找到图片，请将要发送的图片与消息一同发送或引用要添加的图像..')
    cd = true
    //想要群员随意上传可注释下面全部代码
    if (!e.isMaster) {
      let msg
      msg = [`[通知 - 上传${id}${e.msg.includes('彩蛋') ? '彩蛋' : ''}面板图申请]\n群号:${e.group_id}\n群名:${e.group_name}\n群成员:${e.nickname}\n群成员QQ:${e.user_id}\n角色名:${id}`]
      for (let i = 0; i < imageMessages.length; i++) {         
      msg.push(segment.image(imageMessages[i]))
      }
     let mid =  await co.relpyPrivate(cfg.masterQQ[0], msg)  //发给第一个主人
      e.reply('已发送给主人审核', true)
      cd = false
      if (!mid) return
      let data = JSON.parse(await redis.get('Yz:saury:panel'))
      let sup = e.msg.includes('彩蛋') ? true : false
      let json
      if (!data) {
         json = [{mid,id,sup,imgs:imageMessages}]
         await redis.set('Yz:saury:panel',JSON.stringify(json,null,'\t'))
      } else {
         json = {mid,id,sup,imgs:imageMessages}
         data.push(json)
         await redis.set('Yz:saury:panel',JSON.stringify(data,null,'\t'))
      }
      return true
    }
    //想要群员随意上传可注释上面全部代码
    try{
    let namePath = `${path}${id}/`
    let savePath
    let check = true
    if(!fs.existsSync(namePath)) fs.mkdirSync(namePath)
    for (let i = 0; i < imageMessages.length; i++) {
        savePath = await getImageName(`${namePath}${id}`)
        let ret = await co.downFile(imageMessages[i], savePath)
        if (ret) {
          if(!await checkImage(namePath,savePath)) {
            fs.unlinkSync(savePath)
            check = false
           }
        }
      }
      
      e.reply(`上传面板图成功，${check ? '' : '检测到有已存在的图片，已自动跳过，'}可输入【#${id}${e.msg.includes('彩蛋') ? '彩蛋' : ''}面板图列表】查看`)
    } catch (err) {
      logger.error(err)
      e.reply('上传面板图失败')
    }
    
    cd = false
  }

  async letMeLook(e) {
    if (panelList && !e.isMaster) return true
    if (cd) return e.reply('我知道你很急，但你先别急')
    if (e.msg.includes('彩蛋')) {
      path = super_path
    }else{
      path = normal_path
    }
    let id = await this.getId((e))
    if (!id) return e.reply('请输入角色名')
    if(!fs.existsSync(`${path}${id}`)) {
        e.reply(`没有${id}的${e.msg.includes('彩蛋') ? '彩蛋' : ''}角色面板图`)
        return true
    }
    cd = true
    let msglist = []
    try{
    let File = fs.readdirSync(`${path}${id}`)
    msglist.push(`当前查看的是${id}${e.msg.includes('彩蛋') ? '彩蛋' : ''}面板图，共${File.length}张，可输入【#删除${id}${e.msg.includes('彩蛋') ? '彩蛋' : ''}面板图(序列号)】进行删除`)
    for (let i = 0; i < File.length; i++) {
      msglist.push([`${i+1}.`, segment.image(`${path}${id}/${File[i]}`)])
    }

    let msgRsg = await e.reply(await co.makeForwardMsg(e, msglist))
    if (!msgRsg)  e.reply('风控了，可私聊查看', true)
  }catch(err) {
      logger.error(err)
      e.reply('未知错误，请重试')
  }
    cd = false
  }

  async deletePanel(e) {
    let id = await this.getId((e))
    if (!id) return e.reply('请输入角色名')
    if (e.msg.includes('彩蛋')) {
      path = super_path
    }else{
      path = normal_path
    }
    if (e.msg.includes('全部')) {
      try {
      await delDir(`${path}${id}`)
      e.reply(`成功${e.msg.replace(/#/g, '')}`) 
      } catch (err) {
        e.reply(`笨比，本来就没${id}的${e.msg.includes('彩蛋') ? '彩蛋' : ''}角色面板图`)
      }
      return true
    }
    let num = e.msg.match(/\d+/)
    if (!num) {
      e.reply(`删除哪张呢？请输入数字序列号,可输入【#${id}${e.msg.includes('彩蛋') ? '彩蛋' : ''}面板图列表】查看序列号`)
      return
    }
    
    if(!fs.existsSync(`${path}${id}`)) return e.reply(`没有${id}${e.msg.includes('彩蛋') ? '彩蛋' : ''}面板图，无法删除`)
    try{
    let File = fs.readdirSync(`${path}${id}`)
    fs.unlinkSync(`${path}${id}/${File[num - 1]}`)
    e.reply('删除成功')
    } catch(err) {
      e.reply('删除失败，请检查序列号是否正确')
    }
    
  }
  

  async adopt(e) {
    if(!e.isMaster) return false
    if(!e.source) return false
    try{
    let source
    let groupId
    let userId
    let id
    let imageMessages = []
    if (e.isGroup) {
      source = (await e.group.getChatHistory(e.source ?.seq, 1)).pop()
    } else {
      source = (await e.friend.getChatHistory((e.source ?.time + 1), 1)).pop()
    }
    if (source) {
      for (let val of source.message) {
        if (val.type === 'image') {
          imageMessages.push(val.url)
        }
        if (val.type === 'text') {
           id = val.text.match(/角色名:.*/)[0].replace(/角色名:/g, '')
           groupId = val.text.match(/群号:.*/g)[0].replace(/群号:/g, '')
           userId = val.text.match(/群成员QQ:.*/g)[0].replace(/群成员QQ:/, '')
        }
      }
    }
    if (!imageMessages.length) return e.reply('引用的信息里没有图片')
    if (e.msg.includes('彩蛋')) {
      path = super_path
    }else{
      path = normal_path
    }
      let namePath = `${path}${id}/`
      let check = true
      if(!fs.existsSync(namePath)) fs.mkdirSync(namePath)
      for (let i = 0; i < imageMessages.length; i++) {
      let savePath = await getImageName(`${namePath}${id}`)
      let ret = await co.downFile(imageMessages[i], savePath)
      if (ret) {
        if(!await checkImage(namePath,savePath)) {
          fs.unlinkSync(savePath)
          check = false
         }
     }
      }
      e.reply(`上传面板图成功，${check ? '' : '检测到有已存在的图片，已自动跳过，'}可输入【#${id}${e.msg.includes('彩蛋') ? '彩蛋' : ''}面板图列表】查看`)
      if(groupId && userId) {
      Bot.pickGroup(groupId).sendMsg([segment.at(userId),`恭喜你，主人通过了你的上传${id}${e.msg.includes('彩蛋') ? '彩蛋' : ''}面板图请求`])
      }
      } catch (err) {
        logger.error(err)
        e.reply('上传面板图失败')
      }
  }

  async selectAdopt(e) {
    if (!e.isMaster) return
    let data = JSON.parse(await redis.get('Yz:saury:panel'))
    if (!data) return e.reply('暂无上传面板图申请')
    let msg = [`共有${data.length}条上传面板图申请，指令有[一键(通过|拒绝)全部面板图][一键(通过|拒绝)面板图1,3,5]`]
    for (let i = 0; i < data.length; i++) {
    let reply = await Bot.getMsg(data[i].mid.message_id)
    msg.push(`${i+1}.` ,reply.message)
    }
   e.reply(await co.makeForwardMsg(e,msg))
  }

  async adoptAll(e) {
    if (!e.isMaster) return
    let data = JSON.parse(await redis.get('Yz:saury:panel'))
    if (!data) return e.reply('暂无上传面板图申请')
    if (/全部/.test(e.msg)) {
      if(/拒绝/.test(e.msg)) {
        await redis.del('Yz:saury:panel')
        e.reply('一键拒绝成功')
        return true
      }
      let check = true
      for (let i = 0; i < data.length; i++) {
        for (let j = 0; j < (data[i].imgs).length; j++) { 
         path = data[i].sup ? super_path : normal_path
         let namePath = `${path}${data[i].id}/`
         if(!fs.existsSync(namePath)) fs.mkdirSync(namePath)
         let savePath = await getImageName(`${namePath}${data[i].id}`)
         let ret = await co.downFile(data[i].imgs[j], savePath)
         if (ret) {
          if(!await checkImage(namePath,savePath)) {
           fs.unlinkSync(savePath)
           check = false
          }
        }
      }
    }
    e.reply(`一键通过成功${check ? '' :'，检测到有已存在的图片，已自动跳过'}`)
    await redis.del('Yz:saury:panel')
    return true
  }
    let num = e.msg.match(/\d+/g)
    if (!num) return e.reply('序列号呢？')
    if(/通过/.test(e.msg)) {
      let check = true
      for (let i = 0; i < num.length; i++) {
        let number = Number(num[i]) - 1
        for (let j = 0; j < (data[number].imgs).length; j++) {
        path = data[number].sup ? super_path : normal_path
        let namePath = `${path}${data[number].id}/`
        if(!fs.existsSync(namePath)) fs.mkdirSync(namePath)
        let savePath = await getImageName(`${namePath}${data[number].id}`)
        let ret = await co.downFile(data[number].imgs[j], savePath)
        if (ret) {
          if(!await checkImage(namePath,savePath)) {
            fs.unlinkSync(savePath)
            check = false
           }
        }
        }
      }
      e.reply(`一键通过成功${check ? '' :'，检测到有已存在的图片，已自动跳过'}`)
      let arr = []
      for (let i = 0; i < num.length; i++) {
      let number = Number(num[i]) - 1
      arr.push(data[number])  
      }
      for (let i = 0; i < arr.length; i++) {
        await data.splice(data.indexOf(arr[i]),1)
      }
      await redis.set('Yz:saury:panel',JSON.stringify(data,null,'\t'))
      return true
    } else {
      let arr = []
      for (let i = 0; i < num.length; i++) {
      let number = Number(num[i]) - 1
      arr.push(data[number])  
      }
      for (let i = 0; i < arr.length; i++) {
        await data.splice(data.indexOf(arr[i]),1)
      }
      await redis.set('Yz:saury:panel',JSON.stringify(data,null,'\t'))
      e.reply('一键拒绝成功')
      return true
    }
    
    
  }
  //cv椰羊
  async shield(e) {
    if (!original) return false
    if (!e.source) return false
    if (e.isMaster) return false //主人可以获取
    let source = (await e.group.getChatHistory(e.source.seq, 1)).pop()
    let key = `miao:original-picture:${source.message_id}`
    let res = await redis.get(key)
    if (!res || /character-img/.test(res)) return false
    e.reply(segment.image('https://gchat.qpic.cn/gchatpic_new/746659424/4144974507-2439053290-125E4E51B9D45F2C955E6675AF7C6CEE/0?term=3&is_origin=0'))
    return true
  }
  async getId(e) {
    let id = e.msg.replace(/#|面板图|列表|上传|删除|全部|彩蛋|\d+/g, '').trim()
    let nameArr = gsCfg.getAllAbbr()
    for (let rolename of Object.values(nameArr)) {
      if (rolename.includes(id)) {
        id = rolename[0]
        return id
      }  
}
    return false
  }
 
  //cv ap-plugin
  async removeBackGround(e) {
    if (!isRemove) return false
    if (!URL)
    return await e.reply("请先配置去背景所需API，配置教程：https://www.wolai.com/sSZM1AHnBULxyc4s4hKquF")
    const API = 'https://' + URL.split('/')[4] + '-anime-remove-background.hf.space/api/queue/'
    logger.warn(API)
    if (FiguretypeUser[e.user_id]) {
      e.reply('当前有任务在列表中排队，请不要重复发送，去背景完成后会自动发送结果，如果长时间没有结果，请等待1分钟再试', false, { at: true, recallMsg: 15 })
      return true
  }
    if (e.source) {
      let reply
      if (e.isGroup) {
          reply = (await e.group.getChatHistory(e.source.seq, 1)).pop()?.message;
      } else {
          reply = (await e.friend.getChatHistory(e.source.time, 1)).pop()?.message;
      }
      if (reply) {
          for (let val of reply) {
              if (val.type == "image") {
                  e.img = [val.url];
                  break;
              }
          }
      }
  } 
  if (!e.img) return e.reply('消息中未找到图片，请将要发送的图片与消息一同发送或引用要去背景的图像...')
  e.reply('正在为图像去背景，请稍候...', false, { at: true, recallMsg: 15 })
  FiguretypeUser[e.user_id] = setTimeout(() => {
    if (FiguretypeUser[e.user_id]) {
        delete FiguretypeUser[e.user_id];
    }
}, 60000);
let start = new Date()
let img = await axios.get(e.img[0], {
    responseType: 'arraybuffer'
});
let base64 = Buffer.from(img.data, 'binary')
    .toString('base64');
let hash = await getHash(e);
let response = await axios.post(
    API + `push/`, {
    'fn_index': 1,
    'data': [
        'data:image/jpeg;base64,' + base64
    ],
    'action': 'predict',
    'session_hash': hash
},
)
let statushash = response.data.hash
console.log(`本次请求hash为${statushash}`)
let res = await axios.post(
    API + 'status/',
    {
        'hash': statushash
    },
)
let status = res.data.status
console.log(`本次请求状态为${status}`)
while (status != 'COMPLETE') {
    res = await axios.post(
        API + 'status/',
        {
            'hash': statushash
        },
    )
    status = res.data.status
    console.log(`本次请求状态为${status}`)
    await new Promise((resolve) => setTimeout(resolve, 1000));
}
console.log(`本次请求完成`)
let end = new Date()
let time = ((end.getTime() - start.getTime()) / 1000).toFixed(2)
e.reply(`耗时${time}s，正在发送结果...`, false, { at: true, recallMsg: 15 })
res.data.data.data[1] = res.data.data.data[1].replace(/^data:image\/png;base64,/, "")
let buffer = Buffer.from(res.data.data.data[1], 'base64')
await e.reply(segment.image(buffer), true)
delete FiguretypeUser[e.user_id];
return true
 }
}

async function delDir(dir) {
    let files = fs.readdirSync(dir)
    for (let v of files) {
        let newpath = dir + "/" + v
        let stats = fs.statSync(newpath)
        if (stats.isFile()) {
            fs.unlinkSync(newpath)
        } else {
            delDir(newpath)
        }
    }
    // 文件夹里面的都删除之后，删除本文件夹
    fs.rmdirSync(dir)
}

async function getHash(e) {
  let hash = '';
  let chars = '0123456789abcdefghijklmnopqrstuvwxyz';
  for (let i = 0; i < 10; i++) {
      hash += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return hash;
}

async function getImageName(namePath) {
  let name = 'undefined'
  for (let i = 1; i < 114514; i++) {
    let imageName = `${namePath}${i}.webp`
    if (fs.existsSync(imageName)) continue
      name = imageName
      break
  }
  return name
}

async function checkImage(path,imgPath) {
  let buffers = fs.readFileSync(imgPath)
  let base64 = Buffer.from(buffers, 'base64').toString()
  let imgMd5 = MD5(base64)
  let data = fs.readdirSync(path)
  for (let i = 0; i < data.length; i++) {
    let name = path + data[i]
    if (name == imgPath) continue
    let buff = fs.readFileSync(name)
    let base = Buffer.from(buff, 'base64').toString()
    let md5 = MD5(base)
    if (md5 == imgMd5) {
      return false
    }
  }
  return true
}